﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using Moq;
using NUnit.Framework;
using OpenWaves.Video.Web;
using OpenWaves.Video.Web.Controls;

namespace OpenWaves.Video.UnitTests.Web
{
    [TestFixture]
    public class VideoControlTests
    {
        private const string VideoId = "123";

        [Test]
        public void When_Video_Url_Is_Not_Supported_Exception_Is_Raised()
        {
            var websiteVideoApiMock = new Mock<IVideoWebsiteApi>();
            websiteVideoApiMock
                .Setup(s => s.GetVideo(It.IsAny<string>()))
                .Throws<NotSupportedException>();

            using (ServiceLocator.SetScopedResolver(new BasicResolver().Register<IVideoWebsiteApi>(websiteVideoApiMock.Object)))
            {
                var video = new Video.Web.Controls.Video
                                {
                                    Width = 100,
                                    Height = 100,
                                    VideoUrl = "/foo.flv",
                                };

                var videoThumbnail = new VideoThumbnail
                                         {
                                             Width = 100,
                                             Height = 100,
                                             VideoUrl = "/foo.flv",
                                         };

                Assert.Throws(typeof (NotSupportedException), () => RenderControl(video));
                Assert.Throws(typeof (NotSupportedException), () => RenderControl(videoThumbnail));
            }
        }

        [Test]
        public void When_Embed_Control_Factory_Is_Not_Supporting_Video_Type_Exception_Is_Raised()
        {
            var websiteVideoApiMock = new Mock<IVideoWebsiteApi>();
            websiteVideoApiMock
                .Setup(s => s.GetVideo(It.IsAny<string>()))
                .Returns(new DummyVideo
                             {
                                 Thumbnails = new[] { new DummyThumbnail { Height = 5, Url = VideoId, Width = 5 } }
                             });


            using (ServiceLocator.SetScopedResolver(new BasicResolver().Register<IVideoWebsiteApi>(websiteVideoApiMock.Object)
                                                                       .Register<IVideoEmbedControlFactory>(new VideoEmbedControlFactory())))
            {
                var video = new Video.Web.Controls.Video
                                {
                                    Width = 200,
                                    Height = 100,
                                    VideoUrl = "/foo.flv",
                                };

                Assert.Throws(typeof (NotSupportedException), () => RenderControl(video));
            }
        }

        [Test]
        public void When_Video_Url_Is_Supported_Proper_EmbedUrl_Is_Rendered()
        {
            var websiteVideoApiMock = new Mock<IVideoWebsiteApi>();
            websiteVideoApiMock
                .Setup(s => s.GetVideo(It.IsAny<string>()))
                .Returns(new DummyVideo
                             {
                                 Thumbnails = new[] {new DummyThumbnail {Height = 5, Url = VideoId, Width = 5}}
                             });


            var embedControlFactoryMock = new Mock<IVideoEmbedControlFactory>();
            embedControlFactoryMock
                .Setup(s => s.CreateEmbedControl(It.IsAny<IVideo>(), It.IsAny<string>(), It.IsAny<bool>()))
                .Returns(() =>
                             {
                                 var control = new HtmlGenericControl("iframe");
                                 control.Attributes.Add("src", VideoId);
                                 return control;
                             });
      

            using (ServiceLocator.SetScopedResolver(new BasicResolver().Register<IVideoWebsiteApi>(websiteVideoApiMock.Object)
                                                                       .Register<IVideoEmbedControlFactory>(embedControlFactoryMock.Object)))
            {
                var video = new Video.Web.Controls.Video
                                {
                                    Width = 100,
                                    Height = 100,
                                    VideoUrl = "/foo.flv",
                                };

                Assert.That(RenderControl(video).Contains(VideoId));
            }
        }

        [Test]
        public void When_Video_Url_Is_Supported_Proper_Thumbnail_Is_Rendered()
        {
            var websiteVideoApiMock = new Mock<IVideoWebsiteApi>();
            websiteVideoApiMock
                .Setup(s => s.GetVideo(It.IsAny<string>()))
                .Returns(new DummyVideo
                             {
                                 Thumbnails = new[] {new DummyThumbnail {Height = 5, Url = VideoId, Width = 5}}
                             });

            using (ServiceLocator.SetScopedResolver(new BasicResolver().Register<IVideoWebsiteApi>(websiteVideoApiMock.Object)))
            {
                var videoThumbnail = new VideoThumbnail
                                         {
                                             Width = 100,
                                             Height = 100,
                                             VideoUrl = "/foo.flv",
                                         };

                Assert.That(RenderControl(videoThumbnail).Contains(VideoId));
            }
        }


        private static string RenderControl(Video.Web.Controls.Video video)
        {
            var sb = new StringBuilder();

            using (var sw = new StringWriter(sb))
            {
                video.RenderControl(new HtmlTextWriter(sw));
            }
            return sb.ToString();
        }


        private static string RenderControl(VideoThumbnail video)
        {
            var sb = new StringBuilder();
            using (var sw = new StringWriter(sb))
            {
                video.RenderControl(new HtmlTextWriter(sw));
            }

            return sb.ToString();
        }



        internal class DummyVideo : IVideo
        {
            public IEnumerable<IVideoThumbnail> Thumbnails { get; set; }
            public string Title { get; set; }

            public string Id { get; set; }
        }

        internal class DummyThumbnail : IVideoThumbnail
        {
            public string Url { get; set; }
            public int Height { get; set; }
            public int Width { get; set; }
        }
    }
}